home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / tex / tex29 / sttexsrc.zoo / src / scan.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-03-13  |  21.1 KB  |  856 lines

  1.  
  2. /*
  3.  * @(#)scan.c 2.5 EPA
  4.  *
  5.  * Copyright 1987,1988 Pat J Monardo
  6.  *
  7.  * Redistribution of this file is permitted through
  8.  * the specifications in the file COPYING.
  9.  *
  10.  * 
  11.  */
  12.  
  13. #include "tex.h"
  14. #include "token.h"
  15. #include "tokenstack.h"
  16. #include "tokenlists.h"
  17. #include "evalstack.h"
  18. #include "box.h"
  19. #include "tfm.h"
  20. #include "dvi.h"
  21. #include "page.h"
  22. #include "scan.h"
  23.  
  24. gord    cur_order;
  25. val     cur_val;
  26. int     cur_val_level = INT_VAL;
  27. int     radix;
  28.  
  29. scan_left_brace ()
  30. {
  31.     get_nbrx_token();
  32.     if (cur_cmd != LEFT_BRACE) {
  33.         print_err("Missing { inserted");
  34.         help_left();
  35.         back_error();
  36.         cur_tok = LEFT_BRACE_TOKEN;
  37.         cur_cmd = LEFT_BRACE;
  38.         cur_chr= '{';
  39.         incr(align_state);
  40.     }
  41. }
  42.  
  43. scan_optional_equals ()
  44. {
  45.     get_nbx_token();
  46.     if (cur_tok != OTHER_TOKEN + '=')
  47.         back_input();
  48. }
  49.  
  50. bool
  51. scan_keyword (s)
  52.     chrs    s;
  53. {
  54.     char    c;
  55.     ptr     p;
  56.     ptr     q;
  57.  
  58.     p = backup_tokens;
  59.     token_link(p) = NULL;
  60.     c = *s;
  61.     while (c != NUL) {
  62.         get_x_token();
  63.         if (cur_cs == 0 && (cur_chr == c || cur_chr == c - 'a' + 'A')) {
  64.             store_new_token(cur_tok);
  65.             incr(s);
  66.             c = *s;
  67.         } else if (cur_cmd != SPACER || p != backup_tokens) {
  68.             back_input();
  69.             if (p != backup_tokens)
  70.                 back_list(token_link(backup_tokens));
  71.             return FALSE;
  72.         }
  73.     }
  74.     flush_list(token_link(backup_tokens));
  75.     return TRUE;
  76. }
  77.  
  78. mu_error ()
  79. {
  80.     print_err("Incompatible glue units");
  81.     help_mu_error();
  82.     error();
  83. }
  84.  
  85. #define scanned_result(CV, CVL) \
  86.     {cur_val = CV; cur_val_level = CVL;}
  87.  
  88. #define negate_glue() \
  89.     {width(cur_val) = -width(cur_val); \
  90.     stretch(cur_val) = -stretch(cur_val); \
  91.     shrink(cur_val) = -shrink(cur_val);}
  92.  
  93. scan_something_internal (level, negative)
  94.     int     level;
  95.     bool    negative;
  96. {
  97.     hword   m;
  98.     int     p;
  99.  
  100.     m = cur_chr;
  101.     switch (cur_cmd)
  102.     {
  103.     case DEF_CODE:
  104.         scan_seven_bit_int();
  105.         if (m == MATH_CODE_BASE) {
  106.             scanned_result(ho(math_code(cur_val)), INT_VAL);
  107.         } else if (m < MATH_CODE_BASE) {
  108.             scanned_result(equiv(m + cur_val), INT_VAL);
  109.         } else {
  110.             scanned_result(eqtb[m + cur_val].i, INT_VAL);
  111.         }
  112.         break;
  113.  
  114.     case TOKS_REGISTER:
  115.     case ASSIGN_TOKS:
  116.     case DEF_FAMILY:
  117.     case SET_FONT:
  118.     case DEF_FONT:
  119.         if (level != TOK_VAL) {
  120.             print_err("Missing number, treated as zero");
  121.             help_missing_number();
  122.             back_error();
  123.             scanned_result(0, DIMEN_VAL);
  124.         } else if (cur_cmd <= ASSIGN_TOKS) {
  125.             if (cur_cmd < ASSIGN_TOKS)  {
  126.                 scan_eight_bit_int();
  127.                 m = TOKS_BASE + cur_val;
  128.             }
  129.             scanned_result(equiv(m), TOK_VAL);
  130.         } else {
  131.             back_input();
  132.             scan_font_ident();
  133.             scanned_result(FONT_ID_BASE + cur_val, IDENT_VAL);
  134.         }
  135.         break;
  136.  
  137.     case ASSIGN_INT:
  138.         scanned_result(eqtb[m].i, INT_VAL);
  139.         break;
  140.  
  141.     case ASSIGN_DIMEN:
  142.         scanned_result(eqtb[m].sc, DIMEN_VAL);
  143.         break;
  144.  
  145.     case ASSIGN_GLUE:
  146.         scanned_result(equiv(m), GLUE_VAL);
  147.         break;
  148.     
  149.     case ASSIGN_MU_GLUE:
  150.          scanned_result(equiv(m), MU_VAL);
  151.          break;
  152.  
  153.     case SET_AUX:
  154.         if (abs(mode) != m) {
  155.             print_err("Improper ");
  156.             print_cmd_chr(SET_AUX, m);
  157.             help_aux();
  158.             error();
  159.             if (level != TOK_VAL) {
  160.                 scanned_result(0, DIMEN_VAL);
  161.             } else {
  162.                 scanned_result(0, INT_VAL);
  163.             }
  164.         } else {
  165.             cur_val = aux; 
  166.             if (m == VMODE)
  167.                 cur_val_level = DIMEN_VAL;
  168.             else cur_val_level = INT_VAL;
  169.         }
  170.         break;
  171.  
  172.     case SET_PREV_GRAF:
  173.         nest[nest_ptr] = cur_list;
  174.         p = nest_ptr;
  175.         while (abs(nest[p].mode_field) != VMODE)
  176.             decr(p);
  177.         scanned_result(nest[p].pg_field, INT_VAL);
  178.         break;
  179.  
  180.     case SET_PAGE_INT:
  181.         if (m == 0) 
  182.             cur_val = dead_cycles;
  183.         else cur_val = insert_penalties;
  184.         cur_val_level = INT_VAL;
  185.         break;
  186.  
  187.     case SET_PAGE_DIMEN:
  188.         if (page_contents == EMPTY)
  189.             if (m == 0)
  190.                 cur_val = MAX_DIMEN; 
  191.             else cur_val = 0;
  192.         else cur_val = page_so_far[m];
  193.         cur_val_level = DIMEN_VAL;
  194.         break;
  195.     
  196.     case SET_SHAPE:
  197.         if (par_shape_ptr == NULL)
  198.             cur_val = 0;
  199.         else cur_val = info(par_shape_ptr);
  200.         cur_val_level = INT_VAL;
  201.         break;
  202.     
  203.     case SET_BOX_DIMEN:
  204.         scan_eight_bit_int();
  205.         if (box(cur_val) == NULL)
  206.             cur_val = 0;
  207.         else cur_val = mem[box(cur_val) + m].sc;
  208.         cur_val_level = DIMEN_VAL;
  209.         break;
  210.     
  211.     case CHAR_GIVEN:
  212.     case MATH_GIVEN:
  213.         scanned_result(cur_chr, INT_VAL);
  214.         break;
  215.     
  216.     case ASSIGN_FONT_DIMEN:
  217.         find_font_dimen(FALSE);
  218.         font_info[fmem_ptr].sc = 0;
  219.         scanned_result(font_info[cur_val].sc, DIMEN_VAL); 
  220.         break;
  221.     
  222.     case ASSIGN_FONT_INT:
  223.         scan_font_ident();
  224.         if (m == 0) {
  225.             scanned_result(hyphen_char[cur_val], INT_VAL);
  226.         } else {
  227.              scanned_result(skew_char[cur_val], INT_VAL);
  228.         }
  229.         break;
  230.  
  231.     case REGISTER:
  232.         scan_eight_bit_int();
  233.         switch (m)
  234.         {
  235.         case INT_VAL:
  236.             cur_val = count(cur_val);
  237.             break;
  238.  
  239.         case DIMEN_VAL:
  240.             cur_val = dimen(cur_val);
  241.             break;
  242.  
  243.         case GLUE_VAL:
  244.             cur_val = skip(cur_val);
  245.             break;
  246.  
  247.         case MU_VAL:
  248.             cur_val = mu_skip(cur_val);
  249.             break;
  250.         }
  251.         cur_val_level = m;
  252.         break;
  253.  
  254.     case LAST_ITEM:
  255.         if (cur_chr == GLUE_VAL)
  256.             cur_val = zero_glue;
  257.         else cur_val = 0;
  258.         cur_val_level = cur_chr;
  259.         if (!is_char_node(tail) && mode != 0) {
  260.             switch (cur_chr)
  261.             {
  262.             case INT_VAL:
  263.                 if (type(tail) == PENALTY_NODE)
  264.                     cur_val = penalty(tail);
  265.                 break;
  266.  
  267.             case DIMEN_VAL:
  268.                 if (type(tail) == KERN_NODE)
  269.                     cur_val = width(tail);
  270.                 break;
  271.  
  272.             case GLUE_VAL:
  273.                 if (type(tail) == GLUE_NODE) {
  274.                     cur_val = glue_ptr(tail); 
  275.                     if (subtype(tail) == MU_GLUE)
  276.                         cur_val_level = MU_VAL;
  277.                 }
  278.                 break;
  279.  
  280.             default:
  281.                 break;
  282.             }
  283.         } else if (mode == VMODE && tail == head) {
  284.             switch (cur_chr)
  285.             {
  286.             case INT_VAL:
  287.                 cur_val = last_penalty;
  288.                 break;
  289.  
  290.             case DIMEN_VAL:
  291.                 cur_val = last_kern;
  292.                 break;
  293.  
  294.             case GLUE_VAL:
  295.                 if (last_glue != MAX_HALFWORD)
  296.                     cur_val = last_glue;
  297.                 break;
  298.             }
  299.         }
  300.         break;
  301.             
  302.     default:
  303.         print_err("You can't use `");
  304.         print_cmd_chr(cur_cmd, cur_chr);
  305.         print("' after ");
  306.         print_esc("the");
  307.         help_thee();
  308.         error();
  309.         if (level != TOK_VAL) {
  310.             scanned_result(0, DIMEN_VAL);
  311.         } else {
  312.             scanned_result(0, INT_VAL);
  313.         }
  314.         break;
  315.     }
  316.     while (cur_val_level > level) {
  317.         if (cur_val_level == GLUE_VAL)
  318.             cur_val = width(cur_val);
  319.         else if (cur_val_level == MU_VAL)
  320.             mu_error();
  321.         decr(cur_val_level);
  322.     }
  323.     if (negative) {
  324.         if (cur_val_level >= GLUE_VAL) {
  325.             cur_val = new_spec(cur_val);
  326.             negate_glue();
  327.         } else negate(cur_val);
  328.     } else if (cur_val_level >= GLUE_VAL && cur_val_level <= MU_VAL)
  329.         add_glue_ref(cur_val);
  330. }
  331.  
  332. scan_seven_bit_int ()
  333. {
  334.     scan_int();
  335.     if (cur_val < 0 || cur_val > 255) {
  336.         print_err("Bad character code");
  337.         help_char();
  338.         int_error(cur_val);
  339.         cur_val = 0;
  340.     }
  341. }
  342.  
  343. scan_eight_bit_int ()
  344. {
  345.     scan_int();
  346.     if (cur_val < 0 || cur_val > 255) {
  347.         print_err("Bad register code");
  348.         help_reg();
  349.         int_error(cur_val);
  350.         cur_val = 0;
  351.     }
  352. }
  353.  
  354. scan_four_bit_int()
  355. {
  356.     scan_int();
  357.     if (cur_val < 0 || cur_val > 15) {
  358.         print_err("Bad number");
  359.         help_number();
  360.         int_error(cur_val);
  361.         cur_val = 0;
  362.     }
  363. }
  364.  
  365. scan_char_num ()
  366. {
  367.     scan_int();
  368.     if (cur_val < 0 || cur_val > 255) {
  369.         print_err("Bad character code");
  370.         help_char_num();
  371.         int_error(cur_val);
  372.         cur_val = 0;
  373.     }
  374. }
  375.  
  376. scan_fifteen_bit_int ()
  377. {
  378.     scan_int();
  379.     if (cur_val < 0 || cur_val > 077777) {
  380.         print_err("Bad math code");
  381.         help_mathchar();
  382.         int_error(cur_val);
  383.         cur_val = 0;
  384.     }
  385. }
  386.  
  387. scan_twenty_seven_bit_int ()
  388. {
  389.     scan_int();
  390.     if (cur_val < 0 || cur_val> 0777777777) {
  391.         print_err("Bad delimiter code");
  392.         help_del();
  393.         int_error(cur_val);
  394.         cur_val = 0;
  395.     }
  396. }
  397.  
  398. #define get_nbsx_token() \
  399.     {negative = FALSE; \
  400.     do {get_nbx_token(); \
  401.         if (cur_tok == MINUS_TOKEN) { \
  402.             negative = !negative; \
  403.             cur_tok = PLUS_TOKEN;} \
  404.     } while (cur_tok == PLUS_TOKEN);}
  405.  
  406. scan_int ()
  407. {
  408.     int     d;
  409.     val     m;
  410.     bool    vacuous;
  411.     bool    negative;
  412.     bool    OK_so_far;
  413.  
  414.     d = 0;
  415.     radix = 0;
  416.     OK_so_far = TRUE;
  417.     get_nbsx_token();
  418.     if (cur_tok == ALPHA_TOKEN) {
  419.         get_token();
  420.         if (cur_tok < CS_TOKEN_FLAG) {
  421.             cur_val = cur_chr;
  422.             if (cur_cmd <= RIGHT_BRACE) {
  423.                 if (cur_cmd == RIGHT_BRACE)
  424.                     incr(align_state);
  425.                 else decr(align_state);
  426.             }
  427.         } else if (cur_tok < CS_TOKEN_FLAG + SINGLE_BASE)
  428.             cur_val = cur_tok - CS_TOKEN_FLAG - ACTIVE_BASE;
  429.         else cur_val = cur_tok - CS_TOKEN_FLAG - SINGLE_BASE;
  430.         if (cur_val > 255) {
  431.             print_err("Improper alphabetic constant");
  432.             help_char_const();
  433.             cur_val = 0;
  434.             back_error();
  435.         } else scan_optional_space();
  436.     } else if (cur_cmd >= MIN_INTERNAL && cur_cmd <= MAX_INTERNAL) {
  437.         scan_something_internal(INT_VAL, FALSE);
  438.     } else {
  439.         radix = 10;
  440.         m = 214748364;
  441.         if (cur_tok == OCTAL_TOKEN) {
  442.             radix = 8;
  443.             m = 02000000000;
  444.             get_x_token();
  445.         } else if (cur_tok == HEX_TOKEN) {
  446.             radix = 16;
  447.             m = 010000000000;
  448.             get_x_token();
  449.         }
  450.         vacuous = TRUE;
  451.         cur_val = 0;
  452.         loop {
  453.             if (cur_tok < ZERO_TOKEN + radix &&
  454.                 cur_tok >= ZERO_TOKEN &&
  455.                 cur_tok <= ZERO_TOKEN + 9)
  456.                 d = cur_tok - ZERO_TOKEN;
  457.             else if (radix == 16) {
  458.                 if (cur_tok <= A_TOKEN + 5 && cur_tok >= A_TOKEN)
  459.                     d = cur_tok - A_TOKEN + 10;
  460.                 else if (cur_tok <= OTHER_A_TOKEN + 5 &&
  461.                     cur_tok >= OTHER_A_TOKEN)
  462.                     d = cur_tok - OTHER_A_TOKEN + 10;
  463.                 else break;
  464.             } else break;
  465.             vacuous = FALSE;
  466.             if  (cur_val >= m && (cur_val > m || d > 7 || radix != 10)) {
  467.                 if (OK_so_far) {
  468.                     print_err("Number too big"); 
  469.                     help_big_num();
  470.                     error();
  471.                     cur_val = INFINITY;
  472.                     OK_so_far = FALSE;
  473.                 }
  474.             } else cur_val = cur_val * radix + d;
  475.             get_x_token();
  476.         }
  477.         if (vacuous) {
  478.             print_err("Missing number, treated as zero");
  479.             help_missing_number();
  480.             back_error();
  481.         } else if (cur_cmd != SPACER)
  482.             back_input();
  483.     }
  484.     if (negative)
  485.         negate(cur_val);
  486. }   
  487.     
  488. #define set_conversion(NUM, DENOM) \
  489.     {num = NUM; denom = DENOM;}
  490.  
  491. scan_dimen (mu, inf, shortcut)
  492.     bool    mu;
  493.     bool    inf;
  494.     bool    shortcut;
  495. {
  496.     val     f;
  497.     int     j;
  498.     int     k;
  499.     scal    v;
  500.     val     num;
  501.     val     denom;
  502.     bool    negative;
  503.     val     save_cur_val;
  504.  
  505.     f = 0;
  506.     negative = FALSE;
  507.     arith_error = FALSE;
  508.     cur_order = NORMAL;
  509.     if (!shortcut) {
  510.         get_nbsx_token();
  511.         if (cur_cmd >= MIN_INTERNAL && cur_cmd <= MAX_INTERNAL) {
  512.             if (mu) {
  513.                 scan_something_internal(MU_VAL, FALSE);
  514.                 if (cur_val_level >= GLUE_VAL) {
  515.                     v = width(cur_val);
  516.                     delete_glue_ref(cur_val); cur_val = v;}
  517.                 if (cur_val_level == MU_VAL)
  518.                     goto attach_sign;
  519.                 if (cur_val_level != INT_VAL)
  520.                     mu_error();
  521.             } else {
  522.                 scan_something_internal(DIMEN_VAL, FALSE);
  523.                 if (cur_val_level == DIMEN_VAL)
  524.                     goto attach_sign;
  525.             }
  526.         } else {
  527.             back_input();
  528.             if (cur_tok == EURO_POINT_TOKEN)
  529.                 cur_tok = POINT_TOKEN;
  530.             if (cur_tok != POINT_TOKEN)
  531.                 scan_int();
  532.             else {
  533.                 radix = 10;
  534.                 cur_val = 0;
  535.             }
  536.             if (cur_tok == EURO_POINT_TOKEN)
  537.                 cur_tok = POINT_TOKEN;
  538.             if (radix == 10 && cur_tok == POINT_TOKEN) {
  539.                 k = 0;
  540.                 get_token();
  541.                 loop {
  542.                     get_x_token();
  543.                     if (cur_tok > ZERO_TOKEN + 9 || cur_tok < ZERO_TOKEN)
  544.                         break;
  545.                     if (k < 17) {
  546.                         dig[k] = cur_tok - ZERO_TOKEN;
  547.                         incr(k);
  548.                     }
  549.                 }
  550.                 f = round_decimals(k);
  551.                 if (cur_cmd != SPACER)
  552.                     back_input();
  553.             }
  554.         }
  555.     }
  556.     if (cur_val < 0) {
  557.         negative = !negative;
  558.         negate(cur_val);
  559.     }
  560.     if (inf) {
  561.         if (scan_keyword("fil")) {
  562.             cur_order = FIL;
  563.             while (scan_keyword("l")) {
  564.                 if (cur_order == FILLL) {
  565.                     print_err("Illegal unit of measure (");
  566.                     print("replaced by filll)");
  567.                     help_filll();
  568.                     error();
  569.                 } else incr(cur_order);
  570.             }
  571.             goto attach_fraction;
  572.         }
  573.     }
  574.     save_cur_val = cur_val;
  575.     get_nbx_token();
  576.     if (cur_cmd < MIN_INTERNAL || cur_cmd > MAX_INTERNAL)
  577.         back_input();
  578.     else {
  579.         if (mu) {
  580.             scan_something_internal(MU_VAL, FALSE);
  581.             if (cur_val_level >= GLUE_VAL) {
  582.                 v = width(cur_val);
  583.                 delete_glue_ref(cur_val);
  584.                 cur_val = v;
  585.             }
  586.             if (cur_val_level != MU_VAL)
  587.                 mu_error();
  588.         } else scan_something_internal(DIMEN_VAL, FALSE);
  589.         v = cur_val;
  590.         goto found;
  591.     }
  592.     if (mu)
  593.         goto not_found;
  594.     if (scan_keyword("em"))
  595.         v = quad(cur_font);
  596.     else if (scan_keyword("ex"))
  597.         v = x_height(cur_font);
  598.     else goto not_found;
  599.     scan_optional_space();
  600.  
  601. found:
  602.     cur_val = nx_plus_y(save_cur_val, v, xn_over_d(v, f, 0200000L));
  603.     goto attach_sign;
  604.  
  605. not_found:
  606.     if (mu)  {
  607.         if (scan_keyword("mu"))
  608.             goto attach_fraction;
  609.         else {
  610.             print_err("Illegal unit of measure (");
  611.             print("mu inserted)");
  612.             help_mu();
  613.             error();
  614.             goto attach_fraction;
  615.         }
  616.     }
  617.     if (scan_keyword("true")) {
  618.         prepare_mag();
  619.         if (mag != 1000) {
  620.             cur_val = xn_over_d(cur_val, 1000L, mag);
  621.             f = (1000 * f + 0200000 * remainder) / mag;
  622.             cur_val += f / 0200000;
  623.             f %= 0200000;
  624.         }
  625.     }
  626.     if (scan_keyword("pt"))
  627.         goto attach_fraction;
  628.     if (scan_keyword("in"))      {set_conversion(7227, 100);}
  629.     else if (scan_keyword("pc")) {set_conversion(12, 1);}
  630.     else if (scan_keyword("cm")) {set_conversion(7227, 254);}
  631.     else if (scan_keyword("mm")) {set_conversion(7227, 2540);}
  632.     else if (scan_keyword("bp")) {set_conversion(7227, 7200);}
  633.     else if (scan_keyword("dd")) {set_conversion(1238, 1157);}
  634.     else if (scan_keyword("cc")) {set_conversion(14856, 1157);}
  635.     else if (scan_keyword("sp")) goto done;
  636.     else {
  637.         print_err("Illegal unit of measure (");
  638.         print("pt inserted)");
  639.         help_dimen();
  640.         error();
  641.         goto attach_fraction;
  642.     }
  643.     cur_val = xn_over_d(cur_val, num, denom);
  644.     f = (num * f + 0200000 * remainder) / denom;
  645.     cur_val += f / 0200000;
  646.     f %= 0200000;
  647.  
  648. attach_fraction:
  649.     if (cur_val >= 0400000)
  650.         arith_error = TRUE;
  651.     else cur_val = cur_val * UNITY + f;
  652.  
  653. done:
  654.     scan_optional_space();
  655.  
  656. attach_sign:
  657.     if (arith_error || abs(cur_val) >= 010000000000) {
  658.         print_err("Dimension too large");
  659.         help_big_dimen();
  660.         error();
  661.         cur_val = MAX_DIMEN;
  662.         arith_error = FALSE;
  663.     }
  664.     if (negative)
  665.         negate(cur_val);
  666. }
  667.  
  668. scan_glue (level)
  669.     int     level;
  670. {
  671.     ptr     q;
  672.     bool    mu;
  673.     bool    negative;
  674.  
  675.     mu = (level == MU_VAL);
  676.     get_nbsx_token();
  677.     if (cur_cmd >= MIN_INTERNAL && cur_cmd <= MAX_INTERNAL) {
  678.         scan_something_internal(level, negative);
  679.         if (cur_val_level >= GLUE_VAL) {
  680.             if (cur_val_level != level)
  681.                 mu_error();
  682.             return;
  683.         }
  684.         if (cur_val_level == INT_VAL)
  685.             scan_dimen(mu, FALSE, TRUE);
  686.         else if (level == MU_VAL)
  687.             mu_error();
  688.     } else {
  689.         back_input();
  690.         scan_dimen(mu, FALSE, FALSE);
  691.         if (negative)
  692.             negate(cur_val);
  693.     }
  694.     q = new_spec(zero_glue);
  695.     width(q) = cur_val;
  696.     if (scan_keyword("plus")) {
  697.         scan_dimen(mu, TRUE, FALSE);
  698.         stretch(q) = cur_val;
  699.         stretch_order(q) = cur_order;
  700.     }
  701.     if (scan_keyword("minus")) {
  702.         scan_dimen(mu, TRUE, FALSE);
  703.         shrink(q) = cur_val;
  704.         shrink_order(q) = cur_order;
  705.     }
  706.     cur_val = q;
  707. }
  708.  
  709. #define DEFAULT_RULE    26214
  710.  
  711. ptr
  712. scan_rule_spec ()
  713. {
  714.     ptr     q;
  715.  
  716.     q = new_rule();
  717.     if (cur_cmd == VRULE) {
  718.         width(q) = DEFAULT_RULE;
  719.     } else {
  720.         height(q) = DEFAULT_RULE;
  721.         depth(q) = 0;
  722.     }
  723.  
  724. reswitch:
  725.     if (scan_keyword("width")) {
  726.         scan_normal_dimen();
  727.         width(q) = cur_val;
  728.         goto reswitch;
  729.     }
  730.     if (scan_keyword("height")) {
  731.         scan_normal_dimen();
  732.         height(q) = cur_val;
  733.         goto reswitch;
  734.     }
  735.     if (scan_keyword("depth")) {
  736.         scan_normal_dimen();
  737.         depth(q) = cur_val;
  738.         goto reswitch;
  739.     }
  740.     return q;
  741. }
  742.  
  743. /*
  744.  *  Help text
  745.  */
  746.  
  747. help_mathchar ()
  748. {
  749.     help2("A numeric math code must be between 0 and 32767.",
  750.     "I changed this one to zero.");
  751. }
  752.  
  753. help_number ()
  754. {
  755.     help2("Since I expected to read a number between 0 and 15,",
  756.     "I changed this one to zero.");
  757. }
  758.  
  759. help_char ()
  760. {
  761.     help2("The numeric code for a character must be between 0 and 255.",
  762.     "I changed this one to zero.");
  763. }
  764.  
  765. help_char_num ()
  766. {
  767.     help2("A character number must be between 0 and 255.",
  768.     "I changed this one to zero.");
  769. }
  770.  
  771. help_char_const ()
  772. {
  773.     help2("A one-character control sequence belongs after a ` mark.",
  774.     "So I'm essentially inserting \\0 here.");
  775. }
  776.  
  777. help_big_num ()
  778. {
  779.     help2("I can only go up to 2147483647='17777777777=\"7FFFFFFF,",
  780.     "so I'm using that number instead of yours.");
  781. }
  782.  
  783. help_missing_number ()
  784. {
  785.     help3("A number should have been here; I inserted `0'.",
  786.     "(If you can't figure out why I needed to see a number,",
  787.     "look up `weird error' in the index to The TeXbook.)");
  788. }
  789.  
  790. help_filll ()
  791. {
  792.     help1("I dddon't go any higher than filll.");
  793. }
  794.  
  795. help_mu ()
  796. {
  797.     help4("The unit of measurement in math glue must be mu.",
  798.     "To recover gracefully from this error, it's best to",
  799.     "delete the erroneous units; e.g., type `2' to delete",
  800.     "two letters. (See Chapter 27 of The TeXbook.)");
  801. }
  802.  
  803. help_mu_error ()
  804. {
  805.     help1("I'm going to assume that 1mu=1pt when they're mixed.");
  806. }
  807.  
  808. help_dimen ()
  809. {
  810.     help6("Dimensions can be in units of em, ex, in, pt, pc,",
  811.     "cm, mm, dd, cc, bp, or sp; but yours is a new one!",
  812.     "I'll assume that you meant to say pt, for printers' points.",
  813.     "To recover gracefully from this error, it's best to",
  814.     "delete the erroneous units; e.g., type `2' to delete",
  815.     "two letters. (See Chapter 27 of The TeXbook.)");
  816. }
  817.     
  818. help_big_dimen ()
  819. {
  820.     help2("I can't work with sizes bigger than about 19 feet.",
  821.     "Continue and I'll use the largest value I can.");
  822. }
  823.  
  824. help_thee ()
  825. {
  826.     help1("I'm forgetting what you said and using zero instead.");
  827. }
  828.  
  829. help_left ()
  830. {
  831.     help4("A left brace was mandatory here, so I've put one in.",
  832.     "You might want to delete and/or insert some corrections",
  833.     "so that I will find a matching right brace soon.",
  834.     "(If you're confused by all this, try typing `I}' now.)")
  835. }
  836.  
  837. help_aux ()
  838. {
  839.     help4("You can refer to \\spacefactor only in horizontal mode;",
  840.     "you can refer to \\prevdepth only in vertical mode; and",
  841.     "neither of these is meaningful inside \\write. So",
  842.     "I'm forgetting what you said and using zero instead.");
  843. }
  844.  
  845. help_del ()
  846. {
  847.     help2("A numeric delimiter code must be between 0 and 2^{27}-1.",
  848.     "I changed this one to zero.");
  849. }
  850.  
  851. help_reg ()
  852. {
  853.     help2("A register number must be between 0 and 255.",
  854.     "I changed this one to zero.");
  855. }
  856.